package cn.qrx.gateway.bind;

import net.sf.cglib.core.Signature;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.InterfaceMaker;
import org.apache.dubbo.rpc.service.GenericService;
import org.objectweb.asm.Type;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author 屈燃希
 * @date 2025/10/1 20:21
 * @content
 */
public class GenericReferenceProxyFactory {

    private final GenericService genericService;

    private final Map<String,IGenericReference> genericReferenceCache = new ConcurrentHashMap<>();


    public GenericReferenceProxyFactory(GenericService genericService) {
        this.genericService = genericService;
    }

/**
 * 创建一个新的IGenericReference实例
 * 使用缓存机制，如果已经存在相同method的实例则直接返回
 * 使用动态代理和字节码增强技术创建代理对象
 * @param method 方法名，用于标识和缓存不同的实例
 * @return 返回创建的或缓存的IGenericReference实例
 */
    public IGenericReference newInstance(String method) {
        return genericReferenceCache.computeIfAbsent(method, k -> {
            // 泛化调用
            GenericReferenceProxy genericReferenceProxy = new GenericReferenceProxy(genericService, method);
            // 创建接口
            InterfaceMaker interfaceMaker = new InterfaceMaker();
            interfaceMaker.add(new Signature(method, Type.getType(String.class), new Type[]{Type.getType(String.class)}), null);
            Class<?> interfaceClass = interfaceMaker.create();
            // 代理对象
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(Object.class);
            // IGenericReference 统一泛化调用接口
            // interfaceClass    根据泛化调用注册信息创建的接口，建立 http -> rpc 关联
            //等价代理类实现接口，GenericReferenceProxy对此接口方法进行代理
            enhancer.setInterfaces(new Class[]{IGenericReference.class, interfaceClass});
            enhancer.setCallback(genericReferenceProxy);
            return (IGenericReference) enhancer.create();
        });
    }
}
